import { IPSAppDEMobWFDynaEditView, IPSAppView, IPSDEForm } from '@ibiz/dynamic-model-api';
import { MobWFDynaEditViewEngine } from '../../../engine';
import { AppDEViewController } from './app-de-view-controller';
import { AppViewEvents, IMobWFDynaEditViewController, IParam } from '../../../interface';
import { LogUtil, ModelTool, Util } from '../../../util';
import { AppModelService, GetModelService } from '../../../app';

export class MobWFDynaEditViewController extends AppDEViewController implements IMobWFDynaEditViewController {
  /**
   * 移动端动态工作流编辑视图实例
   *
   * @public
   * @type { IPSAppDEMobWFDynaEditView }
   * @memberof MobWFDynaEditViewController
   */
  public viewInstance!: IPSAppDEMobWFDynaEditView;

  /**
   * @description 表单实例
   * @type {IPSDEForm}
   * @memberof MobWFDynaEditViewController
   */
  public editFormInstance!: IPSDEForm;

  /**
   * @description 工具栏模型数据
   * @type {Array<any>}
   * @memberof MobWFDynaEditViewController
   */
  public linkModel: Array<any> = [];

  /**
   * @description 是否可编辑
   * @type {boolean}
   * @memberof MobWFDynaEditViewController
   */
  public isEditable: boolean = true;

  /**
   * @description 视图引用数据
   * @type {*}
   * @memberof MobWFDynaEditViewController
   */
  public viewRefData: any = {};

  /**
   * @description 工作流附加功能类型映射关系对象
   * @type {*}
   * @memberof MobWFDynaEditViewController
   */
  public wfAddiFeatureRef: any = {
    reassign: { featureTag: 'REASSIGN', action: 'TransFerTask' },
    addstepbefore: { featureTag: 'ADDSTEPBEFORE', action: 'BeforeSign' },
    sendback: { featureTag: 'SENDBACK', action: 'SendBack' },
    sendcopy: { featureTag: 'SENDCOPY', action: 'sendCopy' },
  };

  /**
   * @description 移动端树视图引擎对象
   * @type {MobWFDynaEditViewEngine}
   * @memberof MobWFDynaEditViewController
   */
  public engine: MobWFDynaEditViewEngine = new MobWFDynaEditViewEngine();

  /**
   * @description 初始化视图实例对象
   * @memberof MobWFDynaEditViewController
   */
  public async initViewInstance() {
    await super.initViewInstance();
    this.viewRefData = await ModelTool.loadedAppViewRef(this.viewInstance);
  }

  /**
   * @description 初始化挂载集合
   * @memberof MobWFDynaEditViewController
   */
  public initMountedMap() {
    this.mountedMap.set('self', false);
  }

  /**
   * @description 引擎初始化
   * @param {IParam} [opts={}]
   * @memberof MobWFDynaEditViewController
   */
  public engineInit(opts: IParam = {}) {
    const appDataEntity = this.viewInstance.getPSAppDataEntity();
    this.engine.init({
      view: this,
      form: this.ctrlRefsMap.get('form'),
      p2k: '0',
      isLoadDefault: this.viewInstance.loadDefault,
      keyPSDEField: appDataEntity?.codeName?.toLowerCase(),
      majorPSDEField: ModelTool.getAppEntityMajorField(appDataEntity)?.codeName?.toLowerCase(),
    });
  }

  /**
   * @description 视图挂载
   * @memberof MobWFDynaEditViewController
   */
  public viewMounted() {
    super.viewMounted();
    if (this.viewParam && this.viewParam.actionForm) {
      this.computeActivedForm(this.viewParam.actionForm);
    } else {
      this.computeActivedForm(null);
    }
  }

  /**
   * @description 计算激活表单
   * @param {*} inputForm
   * @memberof MobWFDynaEditViewController
   */
  public computeActivedForm(inputForm: any) {
    if (!inputForm) {
      this.editFormInstance = ModelTool.findPSControlByName('form', this.viewInstance.getPSControls()) as IPSDEForm;
    } else {
      this.editFormInstance = ModelTool.findPSControlByName(
        `wfform_${inputForm.toLowerCase()}`,
        this.viewInstance.getPSControls(),
      ) as IPSDEForm;
    }
    this.mountedMap.set(this.editFormInstance.name, false);
  }

  /**
   * @description 设置已经绘制完成状态
   * @param {string} [name='self']
   * @memberof MobWFDynaEditViewController
   */
  public setIsMounted(name: string = 'self') {
    super.setIsMounted(name);
    if (this.editFormInstance?.name == name) {
      this.viewState.next({
        tag: this.editFormInstance.name,
        action: 'autoload',
        data: { srfkey: this.context[this.appDeCodeName.toLowerCase()] },
      });
    }
  }

  /**
   * @description 获取工具栏按钮
   * @param {*} arg
   * @return {*}  {Promise<any>}
   * @memberof MobWFDynaEditViewController
   */
  public async getWFLinkModel(arg: any): Promise<any> {
    let datas: any = {};
    if (Object.keys(this.viewParam).length > 0) {
      Object.assign(datas, { processDefinitionKey: this.viewParam.processDefinitionKey });
      Object.assign(datas, { taskDefinitionKey: this.viewParam.taskDefinitionKey });
    }
    const response: any = await this.appDataService.GetWFLink({ ...this.context }, datas);
    if (response && response.status === 200) {
      this.linkModel = response.data;
      if (response.headers && response.headers['process-mobform']) {
        this.computeActivedForm(response.headers['process-mobform']);
      } else {
        this.computeActivedForm(null);
      }
    } else {
      const { data: _data } = response;
      App.getNoticeService().error(_data.message);
    }
    return response;
  }

  /**
   * @description 动态工具栏点击
   * @param {*} linkItem
   * @param {*} $event
   * @memberof MobWFDynaEditViewController
   */
  public dynamicToolbarClick(linkItem: any, $event: any) {
    const _this: any = this;
    let datas: any[] = [];
    let xData: any = this.ctrlRefsMap.get('form');
    if (xData.getDatas && xData.getDatas instanceof Function) {
      datas = [...xData.getDatas()];
    }
    const submit: Function = (submitData: any, linkItem: any) => {
      xData.wfsubmit(submitData, linkItem).then((response: any) => {
        if (!response || response.status !== 200) {
          return;
        }
        const { data: _data } = response;
        if (_this.viewdata) {
          this.viewEvent(AppViewEvents.DATA_CHANGE, [{ ..._data }])
          this.viewEvent(AppViewEvents.CLOSE, {});
        } else {
          this.closeView([{ ..._data }]);
        }
      });
    };
    const submitAction: Function = () => {
      if (linkItem && linkItem.sequenceflowview) {
        const targetViewRef: any = this.viewRefData.find((item: any) => {
          return item.name === `WFACTION@${linkItem.sequenceflowview}`;
        });
        if (targetViewRef) {
          let tempContext: any = Util.deepCopy(_this.context);
          Object.assign(tempContext, { [this.appDeCodeName.toLowerCase()]: datas && datas[0].srfkey });
          let tempViewParam: any = { actionView: linkItem.sequenceflowview, actionForm: linkItem.sequenceflowform };
          Object.assign(tempContext, { viewpath: targetViewRef?.getRefPSAppView?.path });
          GetModelService(tempContext).then((modelService: AppModelService) => {
            modelService.getPSAppView(targetViewRef?.getRefPSAppView?.path).then((viewResult: IPSAppView) => {
              //  TODO 国际化
              const viewComponent = App.getComponentService().getViewTypeComponent(
                viewResult.viewType,
                viewResult.viewStyle,
                viewResult.getPSSysPFPlugin()?.pluginCode,
              );
              const appmodal = App.getOpenViewService().openModal(
                {
                  viewComponent: viewComponent,
                },
                tempContext,
                tempViewParam,
              );
              appmodal.subscribe((result: any) => {
                if (!result || !Object.is(result.ret, 'OK')) {
                  return;
                }
                let tempSubmitData: any = Util.deepCopy(datas[0]);
                if (result.datas && result.datas[0]) {
                  const resultData: any = result.datas[0];
                  if (Object.keys(resultData).length > 0) {
                    let tempData: any = {};
                    Object.keys(resultData).forEach((key: any) => {
                      if (resultData[key] && key !== 'srfuf') tempData[key] = resultData[key];
                    });
                    Object.assign(tempSubmitData, tempData);
                  }
                }
                submit([tempSubmitData], linkItem);
              });
            });
          });
        }
      } else {
        submit(datas, linkItem);
      }
    };
    if (linkItem && linkItem.type) {
      if (Object.is(linkItem.type, 'finish')) {
        submitAction();
      } else {
        this.handleWFAddiFeature(linkItem);
      }
    } else {
      submitAction();
    }
  }

  /**
   * @description 处理工作流辅助功能
   * @param {*} linkItem
   * @return {*} 
   * @memberof MobWFDynaEditViewController
   */
  public handleWFAddiFeature(linkItem: any) {
    let featureTag: string = this.wfAddiFeatureRef[linkItem?.type]?.featureTag;
    if (!featureTag) return;
    let targetViewRef: any = this.viewRefData.find((item: any) => {
      return item.name === `WFUTILACTION@${featureTag}`;
    });
    if (!targetViewRef) {
      LogUtil.warn('将待办任务标记为已读失败');
      return;
    }
    // 准备参数
    let datas: any[] = [];
    let xData: any = this.ctrlRefsMap.get('form');
    if (xData.getDatas && xData.getDatas instanceof Function) {
      datas = [...xData.getDatas()];
    }
    let tempContext: any = Util.deepCopy(this.context);
    Object.assign(tempContext, { [this.appDeCodeName.toLowerCase()]: datas && datas[0].srfkey });
    let tempViewParam: any = { actionView: linkItem.sequenceflowview, actionForm: linkItem.sequenceflowform };
    Object.assign(tempContext, { viewpath: targetViewRef?.getRefPSAppView?.path });
    GetModelService(tempContext).then((modelService: AppModelService) => {
      modelService.getPSAppView(targetViewRef?.getRefPSAppView?.path).then((viewResult: IPSAppView) => {
        const viewComponent = App.getComponentService().getViewTypeComponent(
          viewResult.viewType,
          viewResult.viewStyle,
          viewResult.getPSSysPFPlugin()?.pluginCode,
        );
        const appmodal = App.getOpenViewService().openModal(
          {
            viewComponent: viewComponent,
          },
          tempContext,
          tempViewParam,
        );
        appmodal.subscribe((result: any) => {
          if (!result || !Object.is(result.ret, 'OK')) {
            return;
          }
          let tempSubmitData: any = Util.deepCopy(datas[0]);
          if (result.datas && result.datas[0]) {
            const resultData: any = result.datas[0];
            if (Object.keys(resultData).length > 0) {
              let tempData: any = {};
              Object.keys(resultData).forEach((key: any) => {
                if (resultData[key] && key !== 'srfuf') tempData[key] = resultData[key];
              });
              Object.assign(tempSubmitData, tempData);
            }
            this.submitWFAddiFeature(linkItem, tempSubmitData);
          }
        });
      });
    });
  }

  /**
   * @description 提交工作流辅助功能
   * @param {*} linkItem
   * @param {*} submitData
   * @return {*} 
   * @memberof MobWFDynaEditViewController
   */
  public submitWFAddiFeature(linkItem: any, submitData: any) {
    let tempSubmitData: any = Object.assign(linkItem, { activedata: submitData });
    let action: string = this.wfAddiFeatureRef[linkItem?.type]?.action;
    if (!action) return;
    const service: any = this.appDataService;
    if (service && service[action] && service[action] instanceof Function) {
      service[action](Util.deepCopy(this.context), tempSubmitData)
        .then((response: any) => {
          const { data: data } = response;
          if (!response || response.status !== 200) {
            App.getNoticeService().error(response);
            return;
          }
          let _this: any = this;
          if (_this.viewdata) {
            _this.$emit('view-event', {
              viewName: this.viewInstance.name,
              action: 'viewdataschange',
              data: [{ ...data }],
            });
            _this.$emit('view-event', { viewName: this.viewInstance.name, action: 'close', data: null });
          } else {
            this.closeView([{ ...data }]);
          }
          App.getCenterService().notifyMessage(this.appDeCodeName, 'appRefresh', data);
          App.getNoticeService().success(data?.message ? data.message : '提交数据成功');
        })
        .catch((error: any) => {
          App.getNoticeService().error(error);
        });
    }
  }

  /**
   * @description 将待办任务标记为已读
   * @param {*} data 业务数据
   * @memberof MobWFDynaEditViewController
   */
  public readTask(data: any) {
    this.appDataService
      .ReadTask(this.context, data)
      .then((response: any) => {
        if (!response || response.status !== 200) {
          LogUtil.warn('将待办任务标记为已读失败');
          return;
        }
        App.getCenterService().notifyMessage(this.appDeCodeName, 'appRefresh', data);
      })
      .catch((error: any) => {
        LogUtil.warn('将待办任务标记为已读失败');
      });
  }
}
